#include "stdio.h"
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include "rtservice.h"
#include "data_service_port.h"

#include "cmsis_os.h"
#include "shell.h"
#include "code_table.h"
#include "user_rtc.h"
#include "sys_param.h"
#include "data_monitor.h"
#include "network_module.h"
#include "storage_module.h"
#include "mymalloc_ex.h"

#include "fm25cl64.h"

#include "hj212_client.h"
#include "hj212_client_ops.h"
#include "hj212_pack.h"
#include "hj212_msg.h"
#include "hj212_data_msg/hj212_data_msg.h"

#include "variant.h"

#define RUNINFO_ADDR_BEGIN (7 * 1024 + 512)        // 从铁电存储器的7.5k处开始存储, 共512字节
#define RUNINFO_MAGIC (0x1ea01ea0)
#define RUNINFO_MARK (0xfffffff0)
#define RUNINFO_BLOCK_NUM (8)

struct hj212_runinfo_block         // 运行信息块
{
    uint32_t rptr[10];      // 10个读指针, 暂时只用前四个
    uint32_t reserve[4];    // 16个字节保留，以后可能用于其他地方
    uint32_t magic;
    uint32_t crc;           // 使用HJ212 CRC校验算法
};

struct port_hj212_client;
struct port_longtime_push_source        // 主动上报的数据源
{
    struct hj212_datasource parent;
    int type;
    struct port_hj212_client *client;

    struct hj212_datamsg msg;

    /* 临时变量 */
    storage_save_t record;
};
struct port_time_section_source         // 时间区间的数据源，补足和提取数据
{
    struct hj212_datasource parent;
    int type;
    int begin;
    int end;

    struct port_hj212_client *client;

    struct hj212_datamsg msg;

    /* 临时变量 */
    storage_save_t record;
};

struct pol_state_item
{
    int statecodeid;
    int polcodeid;
    variant_type value; // 值是变体
    time_t time;

    rt_list_t list;
};
struct pol_state_source
{
    struct hj212_datasource parent;

    rt_list_t freelist; // 空闲list
    rt_list_t usedlist; // 已使用list
    osTimerId_t timer;  // 定时器

    struct port_hj212_client *client;

    struct hj212_polstate_msg msg;
};

#define HJ212_REQUEST_INFO_NUM  (2)
#define HJ212_REQUEST_INFO_BASE (4)
#define HJ212_INFO_NUM (HJ212_REQUEST_INFO_NUM + HJ212_REQUEST_INFO_BASE)
struct port_hj212_client
{
    struct hj212_client parent;
    osMutexId_t lock;
    struct port_longtime_push_source datasource[HJ212_MSG_TYPE_DAY - HJ212_MSG_TYPE_RTD + 1];   // 实时/分钟/小时/日数据主动上报
    struct pol_state_source polstate_datasource;    // 污染物状态

    int send_inter;     // 发送间隔, 暂时放这里，正常应该并入系统参数

    /* 实时分钟小时日 请求1 请求2  */
    char name[HJ212_INFO_NUM][20];
    char content[HJ212_INFO_NUM][60];

    int current_request_info;

    rt_list_t list;

    void *user;
};

void *hj212port_malloc(size_t size);
void *hj212port_calloc(unsigned int num, size_t size);
void hj212port_free(void *ptr);

int static_datasource_init(struct port_hj212_client *client);

struct hj212_datasource *hj212port_get_data_source(struct hj212_client *client, int type);
struct hj212_datasource *hj212port_create_hisdata_source(struct hj212_client *client, int type, time_t begin, time_t end);
void hj212port_delete_data_source(struct hj212_client *client, struct hj212_datasource *source);

/* 铁电相关 */
void hj212_runinfo_block_save(int no);
struct hj212_runinfo_block *hj212_runinfo_block_get_instance(int no);

/* 状态参数 */
void hj212_pol_state_push(int polcodeid, int statecodeid, variant_type *value, time_t time);
void hj212_pol_state_pushsource(struct pol_state_source *source,
                                int polcodeid,
                                int statecodeid,
                                variant_type *value,
                                time_t time);


